C++实现科学计算器(附源码)

您所在的位置:网站首页 qt 计算器 C++实现科学计算器(附源码)

C++实现科学计算器(附源码)

2023-11-27 03:35| 来源: 网络整理| 查看: 265

文章目录 C++实现计算器功能概述分析思路四则运算阶乘三角函数 源码

C++实现计算器

前一段时间想巩固一下C++的知识点,就自己动手写了一个科学计算器,主要参考文章:C++实现计算器,又自己加了一些其他的功能。

功能概述

该计算器可以实现的功能为:

四则运算(能识别括号),并且支持小数阶乘三角函数和反三角函数 分析思路

下面我会依次分析各个功能中代码的思路

四则运算

四则运算应该是这个计算器最复杂的部分,要将中缀表达式转换为后缀表达式。因为对于程序来说,转换成后缀表达式要更容易计算些。基本思路如下:

将中缀表达式转换成后缀表达式计算后缀表达式

首先,我们要定义两个栈,分别用来存取操作符和操作数。

stack opt; //操作符栈 stack val; //操作数栈

接下来,我们要定义什么是合法字符:(注意:因为要包含小数运算,所以也要将.包含在内):

char opt_set[10] = "+-*/()=.";

确定没有不合法的字符:

/*判断输入的操作符是否合法*/ bool in_set(char theChar) { for (int i = 0; i switch (theOpt) { case '(': return 0; case '+': case '-': return 1; case '*': case '/': return 2; case ')': return 3; } }

另外,如果用户输入的时候不小心输入了空格,我们也应该能够识别到并将空格给清除掉后继续正常运算,可以加一个函数实现该功能:

/*用于去除空格并检查是否有非法字符*/ bool del_space(string& theString) { string res; for (int i = 0; i } else{ cout c = from[i]; if (isdigit(c)) { to = to + c; theInt *= 10; theInt += c - '0'; state = IN; //状态改为在数字内 } else{ if (state == IN && c == '.') { to = to + '.'; theInt = 0; continue; } if (state == IN && c != '.') { to += ' '; theInt = 0; } if (c == '=') break; else if (c == '(') opt.push(c); else if (c == ')') { while (!opt.empty() && opt.top() != '(') { to += opt.top(); to += ' '; opt.pop(); } opt.pop(); } else { while (true) { if (opt.empty() || opt.top() == '(') opt.push(c); else if (level(c) > level(opt.top())) opt.push(c); else { to += opt.top(); to += ' '; opt.pop(); continue; } break; } } state = OUT; //状态为在数字外 } } while (!opt.empty()) { to += opt.top(); to += ' '; opt.pop(); } return true; }

对得到的后缀表达式进行计算:

/*计算后缀表达式*/ bool compute(string &theExp) { int theInt = 0; //暂存数字 int state = OUT;//初始状态为在数字外 char c; bool dot = false; double count = 1.0; for (int i = 0; i if (isdigit(c)) { theInt *= 10; theInt += c - '0'; state = IN; //状态为在数字内 if (dot == true) count *= 10.0; } if (c == '.') { dot = true; continue; } } else{ dot = false; double ans = theInt / count; count = 1.0; if (state == IN) { val.push(ans); theInt = 0; } double x, y; if (c != ' ') { x = val.top();val.pop(); y = val.top();val.pop(); switch (c) { case '+':val.push(x + y); break; case '-':val.push(y - x); break; case '*':val.push(x * y); break; case '/':val.push(y / x); break; default:cout int number = 0; for (int i = 0; theStr[i] != '!'; i++) { if (isdigit(theStr[i])) { number *= 10; number += theStr[i] - '0'; } } return number; }

如果按照常规方法来计算阶乘,那么仅仅只能计算到20左右就会溢出,所以想要实现更大数字的阶乘,我们不得不用到数组来做这件事情:

/*利用数组求阶乘*/ int cal_factorial(int theInt) { LargeNumberFactorial[0] = 1; LargeNumberFactorial[1] = 1; int digit = 1; for (int i = 1; i LargeNumberFactorial[j] *= i; } for (int j = 1; j for (int k = 1; k string str1 = "sin"; string str2 = "cos"; string str3 = "tan"; string str4 = "arcsin"; string str5 = "arccos"; string str6 = "arctan"; const char* show1, *show2, *show3, *show4, *show5, *show6; show4 = strstr(theStr.c_str(), str4.c_str()); if (show4 != NULL) return 4; show5 = strstr(theStr.c_str(), str5.c_str()); if (show5 != NULL) return 5; show6 = strstr(theStr.c_str(), str6.c_str()); if (show6 != NULL) return 6; show1 = strstr(theStr.c_str(), str1.c_str()); if (show1 != NULL) return 1; show2 = strstr(theStr.c_str(), str2.c_str()); if (show2 != NULL) return 2; show3 = strstr(theStr.c_str(), str3.c_str()); if (show3 != NULL) return 3; return 0; }

识别之后对其中的数字进行提取并进行相应的计算:

/*求三角函数里包含的数字并求出对应的结果*/ double cal_rect_number(string& theStr, int theInt) { int number = 0; for (int i = 0; theStr[i] != ')'; i++) { if (isdigit(theStr[i])) { number *= 10; number += theStr[i] - '0'; } } double ans = 0.0; switch (theInt) { case 1:ans = sin(number); break; case 2:ans = cos(number); break; case 3:ans = tan(number); break; case 4:ans = asin(number); break; case 5:ans = acos(number); break; case 6:ans = atan(number); break; default:return 0; break; } return ans; }

进行相应的测试 (因为比较懒,暂时没有加上小数功能(o゚v゚)ノ): 在这里插入图片描述

源码

上面的分析大概就是这样了,经验不足,可能有些地方写的不是很详细,还请各位见谅(#°Д°),附上源码,可能有潜在的bug,但是目前测试都是正确的:

#include #include #include #include #include #include #include #include using namespace std; stack opt; //操作符栈 stack val; //操作数栈 //求阶乘所用数组 int LargeNumberFactorial[1000] = { 0 }; //定义两个常量表示在数字中的状态 const int IN = 0; const int OUT = 1; char opt_set[10] = "+-*/()=."; int level(char theOpt); //操作符的优先级 bool in_set(char theChar); //判断输入的操作符是否合法,仅包括()+-*/ bool del_space(string &theString); //用于去除空格并检查是否有非法字符 string to_string(int theInt); //把数字转换成字符串 bool change(string &from, string &to); //将中缀表达式转换成后缀表达式 bool compute(string &theExp); //计算后缀表达式 int Judge_rectangle(string& theStr); //判断是否为三角函数或反三角函数并返回对应的编号 double cal_rect_number(string& theStr, int theInt); //求三角函数里包含的数字并求出对应的结果 bool Judge_factorial(string& theStr); //判断是否为求阶乘 int cal_factorial(int theInt); //利用数组求阶乘 int cal_factorial_number(string& theStr); // 求阶乘所求的数字 int main() { cout cout int n = cal_factorial_number(init_exp); cout opt.pop(); } while (!val.empty()) { val.pop(); } del_space(init_exp);//去除空格 string cng_exp; cng_exp.clear(); change(init_exp, cng_exp); //转换为后缀表达式 compute(cng_exp);//计算后缀表达式 double stdans = val.top(); cout case '(': return 0; case '+': case '-': return 1; case '*': case '/': return 2; case ')': return 3; } } /*判断输入的操作符是否合法*/ bool in_set(char theChar) { for (int i = 0; i string res; for (int i = 0; i } else{ cout neg = true; theInt = -theInt; } string res; while (theInt != 0) { char c = (theInt % 10) + '0'; res = c + res; theInt /= 10; } if (neg) res = '-' + res; return res; } /*将中缀表达式转换成后缀表达式*/ bool change(string &from, string &to) { int theInt = 0; int state = OUT; char c; for (int i = 0; i to = to + c; theInt *= 10; theInt += c - '0'; state = IN; //状态改为在数字内 } else{ if (state == IN && c == '.') { to = to + '.'; theInt = 0; continue; } if (state == IN && c != '.') { to += ' '; theInt = 0; } if (c == '=') break; else if (c == '(') opt.push(c); else if (c == ')') { while (!opt.empty() && opt.top() != '(') { to += opt.top(); to += ' '; opt.pop(); } opt.pop(); } else { while (true) { if (opt.empty() || opt.top() == '(') opt.push(c); else if (level(c) > level(opt.top())) opt.push(c); else { to += opt.top(); to += ' '; opt.pop(); continue; } break; } } state = OUT; //状态为在数字外 } } while (!opt.empty()) { to += opt.top(); to += ' '; opt.pop(); } return true; } /*计算后缀表达式*/ bool compute(string &theExp) { int theInt = 0; //暂存数字 int state = OUT;//初始状态为在数字外 char c; bool dot = false; double count = 1.0; for (int i = 0; i if (isdigit(c)) { theInt *= 10; theInt += c - '0'; state = IN; //状态为在数字内 if (dot == true) count *= 10.0; } if (c == '.') { dot = true; continue; } } else{ dot = false; double ans = theInt / count; count = 1.0; if (state == IN) { val.push(ans); theInt = 0; } double x, y; if (c != ' ') { x = val.top();val.pop(); y = val.top();val.pop(); switch (c) { case '+':val.push(x + y); break; case '-':val.push(y - x); break; case '*':val.push(x * y); break; case '/':val.push(y / x); break; default:cout int number = 0; for (int i = 0; theStr[i] != ')'; i++) { if (isdigit(theStr[i])) { number *= 10; number += theStr[i] - '0'; } } double ans = 0.0; switch (theInt) { case 1:ans = sin(number); break; case 2:ans = cos(number); break; case 3:ans = tan(number); break; case 4:ans = asin(number); break; case 5:ans = acos(number); break; case 6:ans = atan(number); break; default:return 0; break; } return ans; } /*判断是否为求阶乘*/ bool Judge_factorial(string& theStr) { int len = theStr.length(); for (int i = 0; i if (isdigit(theStr[i])) { number *= 10; number += theStr[i] - '0'; } } return number; } /*利用数组求阶乘*/ int cal_factorial(int theInt) { LargeNumberFactorial[0] = 1; LargeNumberFactorial[1] = 1; int digit = 1; for (int i = 1; i LargeNumberFactorial[j] *= i; } for (int j = 1; j for (int k = 1; k


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3